package com.strato.mvc.i18n.v1_0_0;

import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.strato.annotation.osgi.v1_0_0.service.OsgiService;
import com.strato.annotation.osgi.v1_0_0.service.OsgiWired;
import com.strato.i18n.v1_0_0.LocaleContext;
import com.strato.i18n.v1_0_0.Messages;
import com.strato.logging.v1_0_0.api.Log;
import com.strato.mvc.api.v1_0_0.control.HttpInvoker;
import com.strato.mvc.api.v1_0_0.control.HttpInvokerInterceptor;
import com.strato.mvc.api.v1_0_0.control.PathVariableCollector;
import com.strato.mvc.api.v1_0_0.model.ModelAndView;
import com.strato.mvc.api.v1_0_0.util.RequestMeta;
import com.strato.mvc.i18n.v1_0_0.resolvers.CookieResolver;
import com.strato.mvc.i18n.v1_0_0.resolvers.DefaultResolver;
import com.strato.mvc.i18n.v1_0_0.resolvers.SessionResolver;

@OsgiService
public class LocaleChangeInterceptor implements HttpInvokerInterceptor {

	@OsgiWired
	private Log log;
	
	public static final String DEFAULT_REQUEST_PARAMETER_NAME="locale";

	private static final int ORDER = 100;
	
	private String requestParameter=DEFAULT_REQUEST_PARAMETER_NAME;
	
	public String getRequestParameter() {
		return requestParameter;
	}

	public void setRequestParameter(String requestParameter) {
		this.requestParameter = requestParameter;
	}

	private LocaleResolver[] localeResolvers=new LocaleResolver[]{CookieResolver.getInstance(),SessionResolver.getInstance(),DefaultResolver.getInstance()};
	
	public LocaleResolver[] getLocaleResolvers() {
		return localeResolvers;
	}

	public void setLocaleResolvers(LocaleResolver[] localeResolvers) {
		this.localeResolvers = localeResolvers;
	}

	@Override
	public boolean canHandle(HttpServletRequest request, HttpServletResponse response, PathVariableCollector pvc, RequestMeta meta, HttpInvoker invoker) {
		return true;
	}

	@Override
	public boolean beforeInvocation(HttpServletRequest request, HttpServletResponse response, PathVariableCollector pvc, ModelAndView mav,HttpInvoker invoker) {
		Locale locale = resolveLocale(request, response);
		LocaleContext.set(locale);
		request.setAttribute("messages", Messages.getInstance());
		return true;
	}

	private Locale resolveLocale(HttpServletRequest request, HttpServletResponse response) {
		String param=request.getParameter(requestParameter);
		if(param!=null){
			if("".equals(param)){//clear
				for(LocaleResolver resolver:localeResolvers){
					resolver.save(null, request, response);
				}
			}else{
				Locale locale=Locale.forLanguageTag(param);
				for(LocaleResolver resolver:localeResolvers){
					resolver.save(locale, request, response);
				}
				return locale;
			}
		}
		Locale locale=null;
		for(LocaleResolver resolver:localeResolvers){
			locale=resolver.load(request, response);
			if(locale!=null){
				return locale;
			}
		}
		return null;
	}

	@Override
	public void invocationSuccess(HttpServletRequest request, HttpServletResponse response, PathVariableCollector pvc, ModelAndView mav, HttpInvoker invoker) {
	}

	@Override
	public void invokeFinally(HttpServletRequest request, HttpServletResponse response, PathVariableCollector pvc, HttpInvoker invoker) {
	}

	@Override
	public void invocationFailed(HttpServletRequest request, HttpServletResponse response, PathVariableCollector pvc, Exception e, HttpInvoker invoker) {
	}

	@Override
	public int getOrder() {
		return ORDER;
	}

}
